const vscode = require('vscode')
const qiniu = require('qiniu')
const tinify = require('tinify')
const fs = require('fs')
const md5 = require('md5')
const { v1: uuid } = require('uuid')
const config = new qiniu.conf.Config()
// 空间对应的机房
config.zone = qiniu.zone.Zone_z0
// 是否使用https域名
config.useHttpsDomain = true
// 上传是否使用cdn加速
config.useCdnDomain = true
const formUploader = new qiniu.form_up.FormUploader(config)
const putExtra = new qiniu.form_up.PutExtra()
const TinyPNG = require('./tinify')
const regImg = /^.*\.(jpg|jpeg|png|webp)$/i // 图片格式
// tinify密钥
const tinifyArr = [
  'TMcdJ3MjwvhKmNXhwczMBwJGnJQ3f75t',
  'CBCFTPTmTNDlQlh8LWWVdBZJrDv5g0WM',
  'HWRkcx2s688YKHfffSkgLShgRgB7h0Yv',
  'jkw5HSXD9ZF83j88ZvB3NSPDh4BpsTxX',
  'sKwzbt0LnT5qj4qKPscCfpYVfrcNjcPz',
  '7zhgWP1mdHsSs126MJpDjx994vncrTwd',
  'fr8G2yfTy46Jh2ssR7dzDss51QpPgmfy',
  '4yL8vt9ns4kkgDqDBwW3GSwpmyJ6282H',
  'nzL4PlvYBv74vsgxTjBMPDsXCZvLqy3X',
  'dkVJXn2lnxcK9CQ956xdQjdXg7C0PTmM'
]
let tinifyIndex = 0
let obj = {}
// 获取七牛上传token
const getToken = (accessKey, secretKey, scope) => {
  const options = {
    scope
  }
  const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
  const putPolicy = new qiniu.rs.PutPolicy(options)
  const uploadToken = putPolicy.uploadToken(mac)
  return uploadToken
}

// 文件hash 值
const getFileHash = (fileName, digt = 16) => {
  const arr = md5(uuid() + fileName).split('')
  arr.length = digt
  return arr.join('')
}

// 将链接插入光标位置
const addUrlToEditor = (url) => {
  let editor = vscode.window.activeTextEditor
  if (!editor) {
    return
  }
  const { start, end, active } = editor.selection
  if (start.line === end.line && start.character === end.character) {
    // 在光标位置插入内容
    const activePosition = active
    editor.edit((editBuilder) => {
      editBuilder.insert(activePosition, url)
    })
  } else {
    // 替换内容
    const selection = editor.selection
    editor.edit((editBuilder) => {
      editBuilder.replace(selection, url)
    })
  }
}

// 图片、文件上传
const uploadFile = (token, pathItem, type, key) => {
  // 获取参数配置
  const { domain } = vscode.workspace.getConfiguration('upload_file')
  formUploader[type](token, key, pathItem, putExtra, function (respErr, respBody, respInfo) {
    if (respErr) {
      throw respErr
    }
    if (respInfo.statusCode === 200) {
      const url = domain + respBody.key
      addUrlToEditor(url)
    } else {
      vscode.window.showWarningMessage(`上传失败: ${respInfo.statusCode}`)
    }
  })
}

// 图片、文件上传 和压缩
const fileUpload = async (fileList) => {
  // 获取参数配置
  const { accessKey, secretKey, scope, domain, gzip } =
    vscode.workspace.getConfiguration('upload_file')

  if (!accessKey || !secretKey || !domain || !scope) {
    vscode.window.showWarningMessage('请配置七牛云上传参数')
    return
  }

  const filePath = fileList[0].path
  const fileArr = filePath.split('/')
  const fileName = fileArr[fileArr.length - 1]
  const type = fileName.split('.')[1]
  const name = fileName.split('.')[0]
  const key = `${name}.${getFileHash(filePath)}.${type}`

  const token = getToken(accessKey, secretKey, scope)
  try {
    if (regImg.test(filePath)) {
      // 压缩上传
      tinify.key = tinifyArr[tinifyIndex]
      const count = await TinyPNG.tinifyValidate(tinify)
      if (count === 500) {
        if (tinifyIndex < tinifyArr.length - 1) {
          tinifyIndex += 1
        }
        if (tinifyIndex === tinifyArr.length - 1) {
          tinifyIndex = 0
        }
        fileUpload(fileList)
        return
      }
      if (gzip) {
        const resultData = await TinyPNG.tinifyCompress(tinify, filePath)
        uploadFile(token, resultData, 'put', key)
        return
      }
    }
    uploadFile(token, filePath, 'putFile', key)
  } catch (error) {
    vscode.window.showErrorMessage(`上传失败: ${error}`)
  }
}

// 网络图片上传七牛云
const onlineImgUpload = (imgUrl, bucketManager, scope, domain) => {
  const type = imgUrl.split('.')[imgUrl.split('.').length - 1]
  const key = `${getFileHash(imgUrl)}.${type}`

  return new Promise((resolve, reject) => {
    bucketManager.fetch(imgUrl, scope, key, function (err, respBody, respInfo) {
      if (err) {
        reject(err)
        throw err
      } else {
        if (respInfo.statusCode == 200) {
          resolve(domain + respBody.key)
        } else {
          console.log(respInfo.statusCode)
          console.log(respBody)
          reject(respInfo)
        }
      }
    })
  })
}

const changeText = (filePath) => {
  const { accessKey, secretKey, scope, domain } = vscode.workspace.getConfiguration('upload_file')
  const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
  const config = new qiniu.conf.Config()
  config.zone = qiniu.zone.Zone_z0
  const bucketManager = new qiniu.rs.BucketManager(mac, config)

  let text = fs.readFileSync(filePath, 'utf8')
  text.replace(/(?<=["|'|(])(.*?)(?=["|'|)])/gi, (item) => {
    if (item.includes('https://ai-sample.oss-cn-hangzhou.aliyuncs.com')) {
      obj[item] = ''
      return item
    }
    return item
  })
  const arr = Object.keys(obj)
  Promise.all(
    arr.map(async (item) => {
      const url = await onlineImgUpload(item, bucketManager, scope, domain)
      obj[item] = url
      return url
    })
  ).then(function () {
    if (Object.keys(obj).length) {
      Object.keys(obj).forEach((item) => {
        if (text.includes(item) && obj[item]) {
          text = text.replace(item, obj[item])
        }
      })
      fs.writeFileSync(filePath, text)
      obj = {}
    }
  })
}

module.exports = {
  fileUpload,
  onlineImgUpload,
  changeText
}
